package org.example.mock;

import lombok.extern.slf4j.Slf4j;
import org.example.bean.AnnualMovieBoxOffice;

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.HashSet;

/**
 * 每年电影票房数据生成器，生成数据并插入数据库
 */
@Slf4j
public class AnnualMovieBoxOfficeGenerator {
    private static final String DB_URL = "jdbc:mysql://192.168.10.102/changchengfilm?requireSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC";
    private static final String DB_USER = "root";
    private static final String DB_PASSWORD = "000000";
    private static final int BATCH_SIZE = 50;
    private static final int TOTAL_RECORDS = 100; // 可根据需要调整生成记录总数

    private static final Random RANDOM = new Random();

    // 模拟国家ID，这里假设从1开始，可根据实际情况调整
    private static int countryIdCounter = 1;
    // 模拟年份，这里设置为近 10 年数据，可按需调整
    private static final int[] YEARS = {2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024};

    public static void main(String[] args) {
        log.info("开始生成{}条每年电影票房模拟数据并插入数据库", TOTAL_RECORDS);

        try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD)) {
            // 清空现有数据
            clearExistingData(conn);

            List<AnnualMovieBoxOffice> dataList = generateMovieBoxOfficeData();
            insertToDatabase(dataList, conn);
            log.info("数据插入完成");
        } catch (SQLException e) {
            log.error("数据库操作失败", e);
        }
    }

    /**
     * 清空 annual_movie_box_office 表中的现有数据
     */
    private static void clearExistingData(Connection conn) throws SQLException {
        log.info("清空 annual_movie_box_office 表中的现有数据");
        try (PreparedStatement pstmt = conn.prepareStatement("DELETE FROM annual_movie_box_office")) {
            pstmt.executeUpdate();
            // 如果需要重置自增ID，根据实际表结构调整
            // try (PreparedStatement alterStmt = conn.prepareStatement("ALTER TABLE annual_movie_box_office AUTO_INCREMENT = 1")) {
            //     alterStmt.executeUpdate();
            // }
        }
    }

    /**
     * 生成每年电影票房模拟数据
     */
    private static List<AnnualMovieBoxOffice> generateMovieBoxOfficeData() {
        List<AnnualMovieBoxOffice> dataList = new ArrayList<>(TOTAL_RECORDS);
        // 用于记录已使用的国家名称组合，确保同一国家同一年数据唯一（可根据实际业务调整唯一性规则）
        Set<String> usedCountryYear = new HashSet<>();

        for (int i = 0; i < TOTAL_RECORDS; i++) {
            Integer countryId = countryIdCounter++;
            String countryName = generateCountryName();
            Integer year = YEARS[RANDOM.nextInt(YEARS.length)];
            // 确保国家 + 年份 组合唯一（示例逻辑，可根据实际需求调整）
            String key = countryName + "_" + year;
            while (usedCountryYear.contains(key)) {
                countryName = generateCountryName();
                year = YEARS[RANDOM.nextInt(YEARS.length)];
                key = countryName + "_" + year;
            }
            usedCountryYear.add(key);

            Integer annualReleasedMovies = RANDOM.nextInt(200) + 1; // 模拟发行电影数量，1 - 200
            BigDecimal annualTotalBoxOffice = new BigDecimal(RANDOM.nextInt(10000000) + 1000000).setScale(2, BigDecimal.ROUND_HALF_UP); // 模拟票房，100万 - 1亿，保留两位小数

            AnnualMovieBoxOffice data = new AnnualMovieBoxOffice();
            data.setCountryId(countryId);
            data.setCountryName(countryName);
            data.setYear(year);
            data.setAnnualReleasedMovies(annualReleasedMovies);
            data.setAnnualTotalBoxOffice(annualTotalBoxOffice);

            dataList.add(data);
        }

        return dataList;
    }

    /**
     * 简单生成国家名称（这里直接从固定列表取，可扩展更复杂逻辑）
     */
    private static String generateCountryName() {
        List<String> countryNames = List.of(
                "中国", "美国", "日本", "英国", "法国", "德国", "俄罗斯", "加拿大", "澳大利亚", "韩国",
                "意大利", "西班牙", "印度", "巴西", "墨西哥", "荷兰", "瑞士", "瑞典", "挪威", "丹麦"
        );
        return countryNames.get(RANDOM.nextInt(countryNames.size()));
    }

    /**
     * 将数据批量插入数据库
     */
    private static void insertToDatabase(List<AnnualMovieBoxOffice> dataList, Connection conn) throws SQLException {
        String sql = "INSERT INTO annual_movie_box_office (country_id, country_name, year, annual_released_movies, annual_total_box_office) VALUES (?, ?, ?, ?, ?)";

        try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
            conn.setAutoCommit(false);

            for (int i = 0; i < dataList.size(); i++) {
                AnnualMovieBoxOffice data = dataList.get(i);
                pstmt.setInt(1, data.getCountryId());
                pstmt.setString(2, data.getCountryName());
                pstmt.setInt(3, data.getYear());
                pstmt.setInt(4, data.getAnnualReleasedMovies());
                pstmt.setBigDecimal(5, data.getAnnualTotalBoxOffice());
                pstmt.addBatch();

                if ((i + 1) % BATCH_SIZE == 0) {
                    pstmt.executeBatch();
                    pstmt.clearBatch();
                }
            }

            if (dataList.size() % BATCH_SIZE != 0) {
                pstmt.executeBatch();
            }

            conn.commit();

        } catch (SQLException e) {
            log.error("执行数据库操作失败", e);
            throw e;
        }
    }
}